package com.knowledge.plus.java8;

import org.junit.Test;

import java.util.function.Function;

/**
 * Lambda表达式只能用于函数式接口（Functional Interface）或者 SAM(Single Abstract Method 单个抽象方法)类型。
 * 函数式接口是指只有一个抽象方法的接口，可以通过`@FunctionalInterface`注解进行标识。
 * 参考：https://www.runoob.com/java/java8-functional-interfaces.html
 * 参考：https://blog.csdn.net/qq_43571809/article/details/134203583
 *
 * @author TPF
 * @since 2023/11/9
 */
public class Lambda表达式 {

    /*
     * 示例：
     * ()：表示该 Lambda 表达式没有参数。在这个例子中，Lambda表达式不接受任何参数。
     * ->：箭头符号，将参数列表和 Lambda 表达式的主体分隔开。
     * {}：花括号内的代码块，表示 Lambda 表达式的具体逻辑。在这个例子中，Lambda表达式的主体是打印 "thread success"。
     */
    @Test
    public void test() throws Exception {
        Runnable runnable = () -> {
            System.out.println("thread success");
        };
        // 简写
        Runnable runnable1 = () -> System.out.println("thread success");
    }


    /**
     * 应用1：作为函数式接口的实例
     * Lambda表达式可以作为函数式接口的实例，通过 Lambda 表达式，可以直接实现函数式接口的抽象方法，而不需要显式地编写实现类。
     */
    public void test1() {
        Runnable runnable = () -> {
            // 执行具体逻辑
        };
    }

    /**
     * 应用2：作为方法的参数
     * Lambda表达式可以作为方法的参数进行传递。这样可以在调用方法时，直接在参数位置上使用 Lambda 表达式来定义方法的具体逻辑。
     */
    public void test2(Function<String, Integer> function) {
        // 执行具体逻辑
    }

    /**
     * 应用3：作为方法的返回值
     * Lambda表达式可以作为方法的返回值进行返回。这样可以在方法内部使用Lambda表达式来定义方法的具体逻辑，并将其返回给调用者。
     */
    public Function<String, Integer> test3() {
        // return (String s) -> s.length();
        return String::length;
    }

    @Test
    public void doSomething() {
        // Lambda表达式可以作为方法的参数进行传递
        test2((String s) -> s.length());
        // 简写，和上面完全相同
        test2(String::length);
    }

}
